import pickle
from PySide6.QtCore import Signal, QObject
from PySide6.QtNetwork import QTcpServer, QAbstractSocket, QHostAddress

class TcpServer(QObject):
    Connected = Signal(str, int)
    DisConnected = Signal()
    DateReceived = Signal(str)

    def __init__(self):
        super().__init__()

        self.__peerIp = ""
        self.__peerPort = 0
        self.__TcpServer = QTcpServer()
        self.__TcpSocket = None

        self.__TcpServer.newConnection.connect(self.on_newConnection)

    def __del__(self):
        self.DisConnect()
        if (self.__TcpSocket is not None):
            self.__TcpSocket.close()
            del self.__TcpSocket
            self.__TcpSocket = None

    def Start(self, port):
        self.__TcpServer.listen(QHostAddress.Any, port)

    def GetIP(self):
        return self.__peerIp

    def GetPort(self):
        return self.__peerPort

    def DisConnect(self):
        self.__peerIp = ""
        self.__peerPort = 0

        if (self.__TcpSocket is not None):
            self.__TcpSocket.disconnectFromHost()

    def SendData(self, json):
        if self.__TcpSocket.state() == QAbstractSocket.ConnectedState:
            return (self.__TcpSocket.write(pickle.dumps(json)) > 0)
        else:
            return False

    def on_newConnection(self):
        while (self.__TcpServer.hasPendingConnections()):
            self.__TcpSocket = self.__TcpServer.nextPendingConnection()
            self.__TcpSocket.readyRead.connect(self.on_readMessage)
            self.__TcpSocket.disconnected.connect(self.on_disconnected)
            self.__TcpSocket.errorOccurred.connect(self.on_displayError)

            self.__peerIp = self.__TcpSocket.peerAddress().toString();
            self.__peerPort = self.__TcpSocket.peerPort()

            self.__peerIp = self.__peerIp[self.__peerIp.rfind(':') + 1:]

            self.Connected.emit(self.__peerIp, self.__peerPort)

    def on_disconnected(self):
        self.__peerIp = ""
        self.__peerPort = 0

        self.DisConnected.emit()

    def on_readMessage(self):
        msg = ""
        while self.__TcpSocket.bytesAvailable():
            # 一次性读取缓存中所有数据
            msg += self.__TcpSocket.readAll()
        #print(msg)
        self.DateReceived.emit(msg)

    def on_displayError(self, socketError):
        #远程服务端关闭连接错误
        if socketError == QAbstractSocket.RemoteHostClosedError:
            self.__TcpSocket.disconnectFromHost()
            print("client close now")
        else:
            print("error id: " + self.__TcpSocket.error().name)
            print("error message: " + self.__TcpSocket.errorString())

